﻿using System;
using System.ComponentModel.Composition;
using MyMusicPlayer.Applications.ViewModels;
using System.Waf.Applications;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using MyMusicPlayer.Utils;
using MyMusicPlayer.Domain;
using System.Collections.ObjectModel;
using MyMusicPlayer.Applications.Services;
using MyMusicPlayer.Presentation.Views;
using System.Media;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace MyMusicPlayer.Applications.Controllers
{
    [Export]
    internal class ControlPanelController
    {
        private readonly IShellService shellService;
        private readonly PlaylistController playlistController;

        private ControlPanelViewModel controlPanelViewModel;
        private PlaylistViewModel playlistViewModel;

        private readonly DelegateCommand previousCommand;   // 上一首
        private readonly DelegateCommand playCommand;       // 播放
        private readonly DelegateCommand pauseCommand;      // 暂停
        private readonly DelegateCommand nextCommand;       // 下一首
        private readonly DelegateCommand changeSpeakerStateCommand; // 切换扬声器的状态：是否静音

        private PlaylistView playlistView;          // 播放列表界面
        private ControlPanelView controlPanelView;  // 控制面板界面
        private double retrieveVolume;              // 记录静音前的音量值，当扬声器变为非静音时，恢复到该值
        //public MediaPlayer mediaPlayer = new MediaPlayer();       // 坑点：不能在按钮点击事件中new，否则很快被GC回收。（放歌3秒钟就停了）
        MediaElement mediaElement;          // 媒体控件。用这个替代MediaPlayer。
        DispatcherTimer dispatcherTimer = new DispatcherTimer();    // 用于时间轴


        [ImportingConstructor]
        public ControlPanelController(IShellService shellService, ControlPanelViewModel controlPanelViewModel,
            PlaylistViewModel playlistViewModel, PlaylistController playlistController)
        {
            this.shellService = shellService;
            this.playlistController = playlistController;

            this.controlPanelViewModel = controlPanelViewModel;
            this.playlistViewModel = playlistViewModel;

            previousCommand = new DelegateCommand(PreviousCommand);
            playCommand = new DelegateCommand(PlayCommand);
            pauseCommand = new DelegateCommand(PauseCommand);
            nextCommand = new DelegateCommand(NextCommand);
            changeSpeakerStateCommand = new DelegateCommand(ChangeSpeakerStateCommand);
        }


        public void Initialize()
        {
            shellService.ControlPanelView = controlPanelViewModel.View;
            controlPanelViewModel.PreviousCommand = previousCommand;
            controlPanelViewModel.PlayCommand = playCommand;
            controlPanelViewModel.PauseCommand = pauseCommand;
            controlPanelViewModel.NextCommand = nextCommand;
            controlPanelViewModel.ChangeSpeakerStateCommand = changeSpeakerStateCommand;

            playlistView = playlistViewModel.View as PlaylistView;
            controlPanelView = controlPanelViewModel.View as ControlPanelView;

            playlistController.PlayMusicAction = this.PlayMusic;

            controlPanelView.playBtn.Visibility = Visibility.Visible;
            controlPanelView.pauseBtn.Visibility = Visibility.Collapsed;

            // 媒体控件的各种事件
            mediaElement = controlPanelView.mediaElement;
            mediaElement.MediaOpened += MediaElement_MediaOpened;
            mediaElement.MediaEnded += MediaElement_MediaEnded;

            // 时间轴
            controlPanelView.timeline.ValueChanged += Timeline_ValueChanged;

            // 音量滑动条
            controlPanelView.volume.ValueChanged += Volume_ValueChanged;
            // 音量回显
            double volume = XMLHelper.GetVolume();
            controlPanelView.volume.Value = volume;         // 音量滑动条
            mediaElement.Volume = volume;  // MediaElement音量
        }

        private void Timeline_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            int timelineValue = (int)controlPanelView.timeline.Value;
            // Overloaded constructor takes the arguments days, hours, minutes, seconds, miniseconds.
            // Create a TimeSpan with miliseconds equal to the slider value.
            TimeSpan ts = new TimeSpan(0, 0, 0, 0, timelineValue);
            mediaElement.Position = ts;
        }

        // 开始播放时
        private void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
        {
            if (mediaElement.NaturalDuration.HasTimeSpan)
            {
                // 设置时间轴slider最大值
                controlPanelView.timeline.Maximum = mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
                dispatcherTimer.Tick += new EventHandler(DispatcherTimer_Tick); // 超过计时器间隔时发生，时间轴向前走1秒
                dispatcherTimer.Interval = new TimeSpan(0, 0, 1); // 间隔1秒
                dispatcherTimer.Start();
            }
        }

        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            // 时间轴slider滑动值随播放内容位置变化
            controlPanelView.timeline.Value = mediaElement.Position.TotalMilliseconds;
            TimeSpan time = mediaElement.Position;
            controlPanelView.position.Content = time.ToString(@"mm\:ss");
        }


        // 播放结束时
        private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            //playlistController.isPlaying = false;
            mediaElement.Stop();
            ChangeBtnVisibility(true);
            playlistController.isMusicEnd = true;
        }


        /// <summary>
        /// 上一首
        /// </summary>
        private void PreviousCommand()
        {
            if (playlistViewModel.MusicList.Count <= 0)
            {
                MessageBox.Show("请先添加歌曲");
                controlPanelView.name.Content = "";
                return;
            }

            MusicInfo musicInfo = null;
            if (playlistController.currMusic == null)
            {
                // 没有任一选中时，播放列表中的第一首歌
                playlistController.currMusic = playlistViewModel.MusicList[0];
            }
            else if (playlistController.currMusic.Index == 1)
            {
                return; // 已经是第一首歌了
            }
            else
            {
                int i = playlistController.currMusic.Index - 1;
                musicInfo = playlistViewModel.MusicList[i - 1];
            }

            if (musicInfo == null)
                return;

            if (!File.Exists(musicInfo.FullPath))
            {
                MessageBox.Show("源文件已被移除了！");
                // 刷新播放列表，移除该音乐。
                playlistController.RemoveItem(playlistController.currMusic);
                return;
            }

            PlayMusic(musicInfo);
        }


        /// <summary>
        /// 下一首
        /// </summary>
        private void NextCommand()
        {
            if (playlistViewModel.MusicList.Count <= 0)
            {
                MessageBox.Show("请先添加歌曲");
                controlPanelView.name.Content = "";
                return;
            }

            MusicInfo musicInfo = null;
            if (playlistController.currMusic == null)
            {
                // 没有任一选中时，播放列表中的第一首歌
                playlistController.currMusic = playlistViewModel.MusicList[0];
            }
            else if (playlistController.currMusic.Index == playlistViewModel.MusicList.Count)
            {
                return; // 已经是最后一首歌了
            }
            else
            {
                int i = playlistController.currMusic.Index + 1;
                musicInfo = playlistViewModel.MusicList[i - 1];
            }

            if (musicInfo == null)
                return;

            if (!File.Exists(musicInfo.FullPath))
            {
                MessageBox.Show("源文件已被移除了！");
                // 刷新播放列表，移除该音乐。
                playlistController.RemoveItem(playlistController.currMusic);
                return;
            }

            PlayMusic(musicInfo);
        }


        /// <summary>
        /// 点击播放按钮
        /// </summary>
        private void PlayCommand()
        {
            if (playlistViewModel.MusicList.Count <= 0)
            {
                MessageBox.Show("请先添加歌曲");
                controlPanelView.name.Content = "";
                return;
            }

            if (playlistController.currMusic == null) // 没有选中任一首歌时，播放列表中的第一首歌
            {
                // 允许之后传参为空，但先检查第一首歌源文件是否存在
                //playlistController.currMusic = playlistViewModel.MusicList[0];
                if (!File.Exists(playlistViewModel.MusicList[0].FullPath))
                {
                    MessageBox.Show("源文件已被移除了！");
                    return;
                }
                PlayMusic(playlistController.currMusic);
            }
            else if (!File.Exists(playlistController.currMusic.FullPath)) // 继续播放当前的音乐，或者换一首歌
            {
                MessageBox.Show("源文件已被移除了！");
                // 刷新播放列表，移除该音乐。
                playlistController.RemoveItem(playlistController.currMusic);
                playlistController.currMusic = null;
                return;
            }
            else
            {
                PlayMusic(playlistController.currMusic);
            }
        }


        /// <summary>
        /// 播放音乐
        /// </summary>
        /// <param name="musicInfo"></param>
        private void PlayMusic(MusicInfo musicInfo)
        {
            if (musicInfo == null) // 还没选歌就按播放键时，自动选播放列表的第一首
            {
                musicInfo = playlistViewModel.MusicList[0];
                // 播放音乐
                mediaElement.Source = new Uri(musicInfo.FullPath, UriKind.Absolute);
                mediaElement.Play();
                // 按钮转变
                ChangeBtnVisibility(false);
                // 修改标记
                playlistController.currMusic = musicInfo;
                //playlistController.isPlaying = true;
                playlistController.isMusicEnd = false;
            }
            else if (playlistController.currMusic == null || !playlistController.currMusic.Id.Equals(musicInfo.Id)) // 第一次选歌、换歌
            {
                // 播放音乐
                mediaElement.Source = new Uri(musicInfo.FullPath, UriKind.Absolute);
                mediaElement.Play();
                // 按钮转变
                ChangeBtnVisibility(false);
                // 修改标记
                playlistController.currMusic = musicInfo;
                //playlistController.isPlaying = true;
                playlistController.isMusicEnd = false;
            }
            else if (playlistController.currMusic.Id.Equals(musicInfo.Id)) // 继续播放当前的音乐
            {
                // 没播放完，从当前位置继续播放；播放完了就重新播放
                if (!File.Exists(playlistController.currMusic.FullPath))
                {
                    MessageBox.Show("源文件已被移除了！");
                    // 刷新播放列表，移除该音乐。
                    playlistController.RemoveItem(playlistController.currMusic);
                    return;
                }

                // 继续播放
                mediaElement.Play();
                // 按钮转变
                ChangeBtnVisibility(false);
                // 修改标记
                //playlistController.isPlaying = true;
                playlistController.isMusicEnd = false;
            }

            // 显示歌名
            controlPanelView.name.Content = playlistController.currMusic.Name;
        }


        /// <summary>
        /// 暂停
        /// </summary>
        private void PauseCommand()
        {
            // 音乐暂停
            mediaElement.Pause();
            // 按钮转变
            ChangeBtnVisibility(true);
            // 修改标记
            //playlistController.isPlaying = false;
            playlistController.isMusicEnd = false;
        }


        /// <summary>
        /// 反转播放按钮、暂停按钮的显隐
        /// </summary>
        /// <param name="isShowPlay">是否要切换为显示播放按钮，隐藏暂停按钮</param>
        public void ChangeBtnVisibility(bool isShowPlay)
        {
            if (isShowPlay)
            {
                controlPanelView.playBtn.Visibility = Visibility.Visible;
                controlPanelView.pauseBtn.Visibility = Visibility.Collapsed;
            }
            else
            {
                controlPanelView.playBtn.Visibility = Visibility.Collapsed;
                controlPanelView.pauseBtn.Visibility = Visibility.Visible;
            }
        }


        // 调节音量
        private void Volume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            // 调节媒体控件的音量
            mediaElement.Volume = controlPanelView.volume.Value;

            if (controlPanelView.volume.Value > 0)
            {
                // 修改Icon
                BitmapImage speakerOnIcon = new BitmapImage();
                speakerOnIcon.BeginInit();
                speakerOnIcon.UriSource = new Uri("pack://application:,,,/Presentation/Resources/Images/speaker_on.png");
                speakerOnIcon.EndInit();
                controlPanelView.speaker.Source = speakerOnIcon;
                // 临时记录音量
                retrieveVolume = controlPanelView.volume.Value;
            }
            else
            {
                // 修改Icon
                BitmapImage speakerOnIcon = new BitmapImage();
                speakerOnIcon.BeginInit();
                speakerOnIcon.UriSource = new Uri("pack://application:,,,/Presentation/Resources/Images/speaker_off.png");
                speakerOnIcon.EndInit();
                controlPanelView.speaker.Source = speakerOnIcon;
            }
        }

        /// <summary>
        /// 切换扬声器的状态：是否静音
        /// </summary>
        private void ChangeSpeakerStateCommand()
        {
            if (controlPanelView.volume.Value > 0)
                controlPanelView.volume.Value = 0;
            else
                controlPanelView.volume.Value = retrieveVolume;
        }

    }
}
